package com.smartapplication.smartringer;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class IncomingCallReceiver extends BroadcastReceiver {
	private AudioManager amanager;
	private static final String TAG = "MyActivity";
	int minVol, maxVol, micSens;
	Boolean active;

	public void onReceive(Context context, Intent intent) {

		SharedPreferences preferences = PreferenceManager
				.getDefaultSharedPreferences(context);
		minVol = Integer.parseInt(preferences.getString("minVolPref", "3"));
		maxVol = Integer.parseInt(preferences.getString("maxxVolPref", "7"));
		micSens = Integer.parseInt(preferences.getString("micSensPref", "0"));
		active = preferences.getBoolean("checkboxEnableService", false);

		Log.v(TAG, "ABC_minVol=" + minVol);
		Log.v(TAG, "ABC_maxVol=" + maxVol);
		Log.v(TAG, "ABC_micSens=" + micSens);

		if (active == true) {

			amanager = (AudioManager) context
					.getSystemService(Context.AUDIO_SERVICE);

			// Turn off the vibration in order to it does not interfere with the measurement
			amanager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
					AudioManager.VIBRATE_SETTING_OFF);
			// Turn off ring in order to it does not interfere with the measurement
			amanager.setStreamVolume(AudioManager.STREAM_RING, 0,
					AudioManager.MODE_RINGTONE);
			// If now there is an incoming call, then ...
			if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
					TelephonyManager.EXTRA_STATE_RINGING)) {
				// run interpolate
				int interpolate = interpolate();
				Toast.makeText(
						context,
						context.getString(R.string.Current_noise_level_is)
								+ currentNoiseB
								+ context.getString(R.string.dB_string)
								+ context
										.getString(R.string.Ringer_volume_set_to)
								+ interpolate, Toast.LENGTH_SHORT).show();
				// Turn on vibration
				amanager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
						AudioManager.VIBRATE_SETTING_ON);
				// Turn on ring and set it level
				amanager.setStreamVolume(AudioManager.STREAM_RING, interpolate,
						AudioManager.MODE_RINGTONE);

			}
		}
	}

	public static NoiseMeter mainNoiseMeter = null;
	private float currentNoise;
	private int currentNoiseB;

	// This method takes the sound level and transforms it into the required format
	public int checkCurrentNoise() {
		mainNoiseMeter = new NoiseMeter();
		mainNoiseMeter.measureStart();
		// this delay is need to wait NoiseMeter is started, otherwise result
		// may be incorrect.
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		currentNoise = mainNoiseMeter.GetCurrentNoise();
		// this is need to protect currentNoise value from unready result.
		while (currentNoise == 0.0) {
			currentNoise = mainNoiseMeter.GetCurrentNoise();
		}
		mainNoiseMeter.measureStop();
		// Round the result to the nearest whole + adjustment of sensitivity
		currentNoiseB = Math.round((int) currentNoise) + micSens;

		return currentNoiseB;
	}

	private int ringerVolume;

	public int interpolate() {

		// The difference between max and min volume level
		int delta = maxVol - minVol;

		// Rounding up is needed to ensure that all values are integer
		// By experimental way it was established that the bandwidth required
		// for the detection of the sound level is 30 dB.
		int step = (int) Math.ceil((float) 30 / delta);
		// Number of key values for the volume levels
		int delta1 = delta + 1; 
		// This array is need to store the volume levels		
		int[] Array = new int[delta1]; 
		// Beginning of measurement range for the phone ZTE Blade is -60 dB.
		// Since the sensitivity of other models may vary, there is
		// "Sensitivity to noise" option is the user interface
		int start = -60;
		// Get noise level
		int CurrentNoise = checkCurrentNoise(); 
		// This variable stores the intermediate values of volume
		int level = -1; 
		Log.v(TAG, "ABC_CurrentNoise=" + CurrentNoise);
		Log.v(TAG, "ABC_delta1=" + delta1);
		// In this cycle, we fill the array with a list of reference values​​,
		// as well as checking the suitability of value under a given condition.
		for (int i = 0; i < delta1; i++) {
			Array[i] = start;
			start = start + step;
			Log.v(TAG, "ABCArray[i]" + Array[i]);
			// If this condition is satisfied, then the required value is found,
			// stop the cycle.
			if (CurrentNoise <= Array[i]) {
				level = i;
				Log.v(TAG, "ABC_level =" + level);
				break;
			}
		}
		// If limit is not reached - that means it's maximum value.
		if (level == -1) {
			level = delta1;
			// That is because that the value of remains larger than the minimum
			// volume.
		} else if (level == 0) {
			level = 1;
		}

		ringerVolume = minVol + level - 1;
		Log.v(TAG, "ABC_ringerVolume =" + ringerVolume);
		return ringerVolume;
	}

}